/*
 * @Author: lin_zizhuo 2297304135@qq.com
 * @Date: 2023-12-07 08:25:46
 * @LastEditors: lin_zizhuo 2297304135@qq.com
 * @LastEditTime: 2023-12-07 15:56:39
 * @FilePath: /thread_text/multipy_thread/mythread.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <vector>
#include <string>
#include <pthread.h>
#include <unistd.h>

using namespace std;
const int num = 5;

// 线程需要有自己独立的栈结构，因为每个线程都必须有自己的调用链
// 主线程的栈在进程地址空间的栈，而新线程的栈由库来维护，放在共享库中
// 所有用户的所有进程的所有线程都会被维护在库中

// 普通的全局变量可以被所有线程拿到，如何让全局变量变成线程私有呢？
// 利用编译选项__thread, 全局变量会被复制一份放在每个线程的暂时存储区，达到私有的效果
__thread int g_val = 100;

struct threadDate
{
    string threadname;
};

void* childRoutine(void* args)
{
    threadDate* date = static_cast<threadDate*>(args);
    int cnt = 5;
    while(cnt)
    {
        cnt--;
        printf("thread: %s, tid: 0x%x, g_val: %d\n", date->threadname.c_str(), pthread_self(), g_val);
        g_val++;
        sleep(1);
    }
    return nullptr;
}

// 虽然栈空间需要独立，但是通过技术手段，是可以做到栈空间互相访问的！因为都存在于当前的地址空间中！

int main()
{
    vector<pthread_t> threads;
    vector<threadDate*> tdd;
    // 创建多个线程
    for(int i = 0; i < num; ++i)
    {
        pthread_t tid;
        threadDate* tddi = new threadDate;
        tddi->threadname = "thread-" + to_string(i);
        tdd.push_back(tddi);
        pthread_create(&tid, nullptr, childRoutine, tddi);
        threads.push_back(tid);
        sleep(1);
    }
    for(auto tid: threads)
        pthread_join(tid, nullptr);
    for(auto tddi: tdd)
        delete tddi;
    return 0;
}